#include "StdAfx.h"
#include "D3DRenderer.h"
#include "chunk.h"

#include "ChunkManager.h"
#include "ChunkDebugMesh.h"

#include "terrainblockchunkitem.h"
#include "TerrainMesh.h"

#include "chunkmodel.h"
#include "ChunkModelDebugMesh.h"

#include "TestApplication.h"

using namespace ChunkSystem;

////////////////////////////////////////////////////////////////////////////////
IRenderable* RenderableFactoryImp::Create(ChunkItem* pChunkItem)
{
	//Todo: refactor later
	Chunk* pChunk = dynamic_cast<Chunk*>(pChunkItem);
	if( pChunk != NULL )
		return new ChunkDebugMesh(pChunk);

	TerrainBlockChunkItem* pTerrainBlock = dynamic_cast<TerrainBlockChunkItem*>(pChunkItem);
	if( pTerrainBlock != NULL )
		return new TerrainMesh(pTerrainBlock);

	ChunkModel* pChunkModelItem = dynamic_cast<ChunkModel*>(pChunkItem);
	if( pChunkModelItem != NULL )
		return new ChunkModelDebugMesh(pChunkModelItem);

	return NULL;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
D3DRenderer::D3DRenderer(LPDIRECT3DDEVICE9 pD3DDevice,TestCamera* pCamera)
	:m_pMeshFactory(new RenderableFactoryImp),m_pCamera(pCamera)
{
	m_pDevice = pD3DDevice;
	assert( m_pDevice != NULL && m_pCamera != NULL );
}
D3DRenderer::~D3DRenderer()
{
	if( m_pMeshFactory != NULL )
		delete m_pMeshFactory;
}

bool D3DRenderer::Draw()
{
	ChunkSpace* pChunkSpace = ChunkManager::GetInstance().GetCurChunkSpace();
	assert( pChunkSpace != NULL );

	ChunkSpace::CurrentChunkMap chunkMap = pChunkSpace->GetCurrentChunk();
	ChunkSpace::CurrentChunkMap::iterator pos = chunkMap.begin();
	for(; pos != chunkMap.end(); ++pos )
	{
		Chunk* pChunk = (*pos).second;
		if( pChunk == NULL )
			continue;

		if( pChunk->GetCurState() != Chunk::eLoaded && pChunk->GetCurState() != Chunk::eBinded ) 
			continue;

		pChunk->DrawVisible( this );
	}

	return true;
}

IRenderableFactory* D3DRenderer::GetRenderableFactory( void )
{
	return m_pMeshFactory;
}

LPDIRECT3DDEVICE9 D3DRenderer::GetD3DDevice(void)
{
	return m_pDevice;
}
